package com.zcl.customcontrols;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import android.app.LocalActivityManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.zcl.iweibo.R;
import com.zcl.utils.NqLog;
import com.zcl.utils.NqUtil;
import com.zcl.utils.Value;

public class TabHostEx extends RelativeLayout implements ViewTreeObserver.OnTouchModeChangeListener {

    private TabWidgetEx mTabWidget; // tabConctrl控件中的标签
    private LocalActivityManager mLocalActivityManager = null; // 管理各页中的activity
    private Vector<TabSpec> mTabSpecs = null; // 存放TabSpec，各个TabSpec里面包含各个tab的信息
    private int mCurrentTab = -1; // 当前被选中的tab
    private FrameLayout mTabContent; // tabConctrl中需要显示页面的地方
    private OnTabChangeListener mOnTabChangeListener; // 当tab页发生改变时触发该Listener
    private View mCurrentView = null; // 当前tab中显示的view
    private OnKeyListener mTabKeyListener; // 当用按键操作标签时，触发该Listener
    private Handler mHandler = null; // 一些操作时给主界面发送消息
    public static final int TABHOST_CLICK_TAB_LABEL = 100; // 点击tab标签时向主窗口发送消息

    private final String TAG = "TabHostEx";

    public TabHostEx(Context context) {
        super(context);
        initVariables(); // 初始化各种变量
    }

    public TabHostEx(Context context, AttributeSet attrs) {
        super(context, attrs);
        initVariables(); // 初始化各种变量
    }

    public TabHostEx(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initVariables(); // 初始化各种变量
    }

    /**
     * 设置handler
     * 
     * @param handler
     */
    public void setHandler(Handler handler) {
        mHandler = handler;
    }

    /**
     * 初始化各种变量
     */
    private void initVariables() {
        mTabSpecs = new Vector<TabSpec>();
    }

    public void setup(LocalActivityManager activityGroup) {
        setup();
        mLocalActivityManager = activityGroup;
    }

    private static final int LAYOUT_BOTTOM_DEFAULT = 60;// DIP 其他页面距离底部的距离,需要与netqin_main_tab中高度定义一致
    private static final int LAYOUT_BOTTOM_NEARBY = 50;// DIP身边距离底部的距离

    /**
     * 设置tabmain中上面部分内容距离屏幕底部的距离
     * 
     * @param tabIndex
     *            各个tab的标识
     */
    private void setLayoutBottom(int tabIndex) {
        int bottom = LAYOUT_BOTTOM_DEFAULT;
        if (tabIndex == Value.EXTRA_LAUNCH_ACTION) {
            bottom = LAYOUT_BOTTOM_NEARBY;
        }

        if (mTabContent != null && mTabContent.getLayoutParams() != null) {
            LayoutParams lp = (LayoutParams) mTabContent.getLayoutParams();
            if (lp instanceof MarginLayoutParams) {
                MarginLayoutParams marginLP = (MarginLayoutParams) lp;
                marginLP.bottomMargin = NqUtil.convertDIP2PX(getContext(), bottom);
            }
        }
    }

    /**
     * 添加tab切换日志
     * 
     * @param tabIndex
     */
    void addTabSelectionLog(int tabIndex) {
        // 好友时，需要判断是否已经登录

    }

    public void setup() {
        // 取出tabWidget和tabContent
        mTabWidget = (TabWidgetEx) findViewById(R.id.tabWidget_ex);
        mTabContent = (FrameLayout) findViewById(R.id.tabcontent_ex);

        setFocusableInTouchMode(true); // 设置在触摸模式下可以获得焦点
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); // This view will get focus only if none
                                                            // of its descendants want it
        // 注册该监听事件，当tab换页时会触发该监听事件
        mTabWidget.setTabSelectionListener(new TabWidgetEx.OnTabSelectionChanged() {
            public void onTabSelectionChanged(int tabIndex, boolean clicked) {


//                addTabSelectionLog(tabIndex);
                if (mHandler != null) {
                    if (tabIndex == Value.EXTRA_LAUNCH_SCHEDULE) {
                        mHandler.sendMessage(mHandler.obtainMessage(TABHOST_CLICK_TAB_LABEL, tabIndex, 0));
                    } else if (tabIndex == Value.EXTRA_LAUNCH_FRIEND && mCurrentTab == tabIndex && clicked) { // 如果有新增动态，则通知NetqinTabMain
                        if (null != mTabWidget/* && mNewFeeds */) {
                            if (Value.printLog) {
                                NqLog.d(TAG, "onTabSelectionChanged_tabIndex == 2");
                            }
                            mHandler.sendMessage(mHandler.obtainMessage(TABHOST_CLICK_TAB_LABEL, tabIndex, 0));
                        }
                    }
                }
                setCurrentTab(tabIndex); // 更换页面
                if (clicked) {
                    mTabContent.requestFocus(View.FOCUS_FORWARD); // 焦点处理
                }
            }
        });

        mTabKeyListener = new OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_CENTER:
                case KeyEvent.KEYCODE_DPAD_LEFT:
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                case KeyEvent.KEYCODE_DPAD_UP:
                case KeyEvent.KEYCODE_DPAD_DOWN:
                case KeyEvent.KEYCODE_ENTER:
                    return false;

                }
                mTabContent.requestFocus(View.FOCUS_FORWARD);
                return mTabContent.dispatchKeyEvent(event);
            }

        };
    }

    public Vector<TabSpec> getTabSpecs() {
        return mTabSpecs;
    }

    public TabWidgetEx getTabWidget() {
        return mTabWidget;
    }

    public void setOnTabChangedListener(OnTabChangeListener l) {
        mOnTabChangeListener = l;
    }

    public void setCurrentTabByTag(String tag) {
        int i;
        for (i = 0; i < mTabSpecs.size(); i++) {
            if (mTabSpecs.get(i).getTag().equals(tag)) {
                setCurrentTab(i);
                break;
            }
        }
    }

    public int getCurrentTab() {
        return mCurrentTab;
    }

    public View getCurrentTabView() {
        if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
            return mTabWidget.getChildTabViewAt(mCurrentTab);
        }
        return null;
    }

    /**
     * 添加tab页
     * 
     * @param intent
     *            每个tab页中的activity对应的intent
     * @param icon
     *            标签上的icon
     * @param text
     *            标签中的文字
     * @param tag
     *            // 标签页中的tag
     */
    public void addTab(Intent intent, Drawable icon, String text, String tag) {
        // tab中的view
        LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View tabIndicator = inflater.inflate(R.layout.tab_indicator, mTabWidget, // tab widget is
                                                                                 // the parent
                false); // no inflate params

        // 设置文字和图片
        final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
        tv.setText(text);
        final ImageView iv = (ImageView) tabIndicator.findViewById(R.id.icon);
        iv.setImageDrawable(icon);

        // 一些属性和消息的注册
        tabIndicator.setFocusable(true);
        tabIndicator.setClickable(true);
        tabIndicator.setOnKeyListener(this.mTabKeyListener);

        // 添加一个标签
        mTabWidget.addView(tabIndicator);

        // 把该标签中的一些信息添加到数组中
        TabSpec spec = new TabSpec(tag);
        spec.setMIntent(intent);
        mTabSpecs.add(spec);

    }

    @Override
    public void dispatchWindowFocusChanged(boolean hasFocus) {
        mCurrentView.dispatchWindowFocusChanged(hasFocus);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        final boolean handled = super.dispatchKeyEvent(event);

        NqLog.d("mCurrentView :"
                + mCurrentView + "mCurrentView.hasFocus() :" + mCurrentView.hasFocus() + " findFocus: " + mCurrentView.findFocus());
        if (!handled && (event.getAction() == KeyEvent.ACTION_DOWN) && (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN)
        /* && (mCurrentView.isRootNamespace()) */
        && (mCurrentView.hasFocus()) && mCurrentView.findFocus() != null && (mCurrentView.findFocus().focusSearch(View.FOCUS_DOWN) == null)) {
            mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
            playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
            return true;
        }
        return handled;
    }

    /**
     * 设置当前页面
     * 
     * @param index
     *            页面的下标值
     */
    public void setCurrentTab(int index) {
        if (index < 0 || index >= mTabSpecs.size()) {
            return;
        }

        // if (index == mCurrentTab) {
        // return;
        // }
        setLayoutBottom(index);
        addTabSelectionLog(index);
        // notify old tab content
        if (mCurrentTab != -1) {
            mTabSpecs.get(mCurrentTab).tabClosed();
        }

        mCurrentTab = index;
        final TabHostEx.TabSpec spec = mTabSpecs.get(index);

        // Call the tab widget's focusCurrentTab(), instead of just
        // selecting the tab.
        mTabWidget.focusCurrentTab(mCurrentTab);

        // tab content
        mCurrentView = spec.getMView();

        final Window w = mLocalActivityManager.startActivity(spec.getTag(), spec.getMIntent());
        final View wd = w != null ? w.getDecorView() : null;

        if (mCurrentView != wd && mCurrentView != null) {
            if (null != mCurrentView.getParent()) {
                mTabContent.removeView(mCurrentView);
            }
        }

        mCurrentView = wd;
        spec.setMView(wd);

        if (null != mCurrentView) {
            mCurrentView.setVisibility(View.VISIBLE);
            mCurrentView.setFocusableInTouchMode(true);
            ((ViewGroup) mCurrentView).setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
        }

        if (null != mCurrentView && null == mCurrentView.getParent()) {
            mTabContent.addView(mCurrentView, new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
        }

        if (!mTabWidget.hasFocus()) {
            // if the tab widget didn't take focus (likely because we're in touch mode)
            // give the current tab content view a shot
            mCurrentView.requestFocus();
        }

        // mTabContent.requestFocus(View.FOCUS_FORWARD);
        invokeOnTabChangeListener();  
    }

    private void invokeOnTabChangeListener() {
        if (mOnTabChangeListener != null) {
            mOnTabChangeListener.onTabChanged(getCurrentTabTag());
        }
    }

    public String getCurrentTabTag() {
        if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
            return mTabSpecs.get(mCurrentTab).getTag();
        }
        return null;
    }

    public interface OnTabChangeListener {
        void onTabChanged(String tabId);
    }

    public void onTouchModeChanged(boolean isInTouchMode) {
        if (!isInTouchMode) {
            // leaving touch mode.. if nothing has focus, let's give it to
            // the indicator of the current tab
            if (mCurrentView != null && (!mCurrentView.hasFocus() || mCurrentView.isFocused())) {
                mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
            }
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        final ViewTreeObserver treeObserver = getViewTreeObserver();
        if (treeObserver != null) {
            treeObserver.addOnTouchModeChangeListener(this);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        final ViewTreeObserver treeObserver = getViewTreeObserver();
        if (treeObserver != null) {
            treeObserver.removeOnTouchModeChangeListener(this);
        }
    }

    /**
     * Removes all tabs from the tab widget associated with this tab host.
     */
    public void clearAllTabs() {
        mTabWidget.removeAllViews();
        /* initTabHost(); */
        mTabContent.removeAllViews();
        mTabSpecs.clear();
        requestLayout();
        invalidate();
    }

    public class TabSpec {
        private String mTag = null;
        private Intent mIntent = null;
        private View mLaunchedView = null;

        private TabSpec(String tag) {
            mTag = tag;
        }

        public String getTag() {
            return mTag;
        }

        public void setMIntent(Intent mIntent) {
            this.mIntent = mIntent;
        }

        public Intent getMIntent() {
            return mIntent;
        }

        public void setMView(View mView) {
            this.mLaunchedView = mView;
        }

        public View getMView() {
            return mLaunchedView;
        }

        public void tabClosed() {
            if (mLaunchedView != null) {
                mLaunchedView.setVisibility(View.GONE);
            }
        }
    }

    public void showFeedTip(int blog) {
        if (null == mTabWidget) {
            return;
        }
        mTabWidget.getChildTabViewAt(Value.EXTRA_LAUNCH_FRIEND).findViewById(R.id.new_feed).setVisibility(blog);
    }

    public void showCurrentTime() {
        long nowTime = System.currentTimeMillis();
        String systemDay = new SimpleDateFormat("d").format(new Date(nowTime));
        TextView tv = (TextView) mTabWidget.getChildTabViewAt(Value.EXTRA_LAUNCH_SCHEDULE).findViewById(R.id.taday_time);
        tv.setVisibility(View.VISIBLE);
        tv.setText(systemDay);
    }
}